#include "udp_ffi.h"


// A very short-lived native function.
//
// For very short-lived functions, it is fine to call them on the main isolate.
// They will block the Dart execution while running the native function, so
// only do this for native functions which are guaranteed to be short-lived.
FFI_PLUGIN_EXPORT int sum(int a, int b) { return a + b; }

// A longer-lived native function, which occupies the thread calling it.
//
// Do not call these kind of native functions in the main isolate. They will
// block Dart execution. This will cause dropped frames in Flutter applications.
// Instead, call these native functions on a separate isolate.
FFI_PLUGIN_EXPORT int sum_long_running(int a, int b) {
  // Simulate work.
#if _WIN32
  Sleep(5000);
#else
  usleep(5000 * 1000);
#endif

  return a + b;
}

FFI_PLUGIN_EXPORT Bytes* encode_ffi(uint8_t *data, int len, uint16_t src, uint16_t dst) {
    LinkList *linkList = decode(data, len, src, dst);
    Bytes *bytess = (Bytes *)malloc(linkList->size * sizeof(Bytes))
    for (int i=0;i<linkList->size;i++){
        Bytes *bytes = (Bytes*)indexGet(i, linkList);
        bytess[i].data = bytes->data;
        bytess[i].len = bytes->len;
    }
    return bytess;
}

typedef void (*OnDataReturn)(uint16_t dst, uint8_t *data, int len, SeqFlag flag);

//using namespace std;

void testFun(int **data, int *len){

    data[0] = (int *) malloc(10 * sizeof(int));
    for (int i = 0; i < 10; i++){
        data[0][i] = (i & 0xFF);
//        std:: cout << "a : " << data[0][i] << std::endl;
    }
    *len = 10;
}

OnDataReturn _onDataReturn;

uint64_t seq = 0;

uint64_t nextSeq(){
    return seq++;
}

//void (*_dart_cb)(uint16_t dst, uint8_t *data, int len, SeqFlag flag);


void publishMesh(int dst, Bytes* bytes){
    //
}



void onDataCallback(uint16_t dst, Bytes *bytes, SeqFlag flag){
    if(flag == BL_FORWARD){
//        std:: cout << " BL_FORWARD " << std::endl;
    }else if(flag == UDP_FORWARD){
//        std:: cout << " UDP_FORWARD " << std::endl;
    }else if(flag ==COMPLETED){
//        std:: cout << " COMPLETED " << std::endl;
        printHex(bytes);
    }else if(flag == SEND_ACK_DATA){
//        std:: cout << " SEND_ACK_DATA " << std::endl;
        printHex(bytes);
    }else if(flag == RECV_ACK_DATA){
//        std:: cout << " RECV_ACK_DATA " << std::endl;
        printHex(bytes);
    }
    _onDataReturn(dst, bytes->data, bytes->len,flag);
}



/**
 *
 */
void onMesh(Bytes *bytes){

    encode(bytes->data, bytes->len);
}



void onUDPReceive(uint8_t *data, int len){

    encode(data, len);

//	LinkList *linkList = decode(data, 25, 0x0001, 0x0002);
//	Iterator iter;iterator(&iter, linkList);
//	while(hasNext(&iter)){
//		Bytes *bytes = (Bytes*)next(&iter);
//
//		publishMesh()
//		printHex(bytes);
//		delNode(&iter);
//	}

}

FFI_PLUGIN_EXPORT void init(OnDataReturn onDataReturn) {

    _onDataReturn = onDataReturn;

    dataBufferCreate(2000);

    // 设置 data mtu
    setDataMTU(10);

    // 如果使用SIG Mesh作为组网转发设置SIG Mesh地址
    myAddress(0x0001);

    // BL_FORWARD
    enableForward(BL_FORWARD | UDP_FORWARD);

    // req number 回调
    nextSeqHandler(&nextSeq);

    // 数据回调
    dataHandler(&onDataCallback);


    uint8_t *data = (uint8_t *)malloc(30 * sizeof(uint8_t));

    data[0] = 0x01;
    for (int i=1;i<30;i++){
        data[i] = i & 0xFF;
    }



//     uint8_t *data,  int len, uint16_t src, uint16_t dst
    LinkList *linkList = decode(data, 30, 0x0002, 0x0001);

    for (int i=0;i<linkList->size;i++){
        Bytes *bytes = (Bytes*)indexGet(i, linkList);
        onUDPReceive(bytes->data, bytes->len);
    }



//
//	int *data;
//	int len;
//	testFun(&data, &len);
//
//	std:: cout << "len  " << len << std::endl;
//	for (int i = 0; i < len; i++)
//	{
//		std:: cout << data[i] << " --- " << std::endl;
//	}
//	free(data);

}


